<?php

namespace App\Repositories\Manage;

use App\Models\Member;
use App\Models\Order;
use App\Models\OrderProduct;
use App\Models\ProductCategory;
use App\Models\Stall;
use App\Models\Supplier;

class StatRepository
{

    public function getMonthStat()
    {

        $model = Order::query()->whereIn("status", [10, 20])
            ->where("create_time", ">=", strtotime(date("Y-m-01")));

        if (!checkIsSuper(UID)) {
            $shop_id = getUserRelateShopId(UID);
            if (empty($shop_id)) {
                return retFail("无查看权限");
            }

            $model->where("shop_id", $shop_id);
        }

        //订单数
        $order_amount = $model->count("id");

        //总销售额
        $order_total_price = $model->sum("total_price");

        //退款金额
        $total_refund_price = $model->sum("refund_price");
        //打包费
//        $total_bag_price = $model->sum("bag_price");

        //配送费
        $total_express_price = $model->sum("express_price");

        //新增会员
        $total_new_member = Member::query()->where("reg_time", ">=", strtotime(date("Y-m-01")))
            ->count("id");

        $total_price = $order_total_price - $total_refund_price;

        if (checkIsSuper(UID)) {
            return retSuc([
                [
                    'title' => "本月订单数",
                    'id' => 'order_amount',
                    'amount' => $order_amount,
                    'icon' => "order"
                ],
                [
                    'title' => "本月销售额",
                    'id' => 'total_price',
                    'amount' => $total_price,
                    'icon' => "money"
                ],
                [
                    'id' => 'ava_price',
                    'title' => "本月平均客单价",
                    'amount' => $order_amount > 0 ? round($total_price / $order_amount, 2) : 0,
                    'icon' => "money"
                ],

                [
                    'id' => 'total_new_member',
                    'title' => "本月新增会员数",
                    'amount' => $total_new_member,
                    'icon' => "visit"
                ],
            ]);
        } else {
            return retSuc([
                [
                    'title' => "本月订单数",
                    'id' => 'order_amount',
                    'amount' => $order_amount,
                    'icon' => "order"
                ],
                [
                    'title' => "本月销售额",
                    'id' => 'total_price',
                    'amount' => $total_price - $total_express_price,
                    'icon' => "money"
                ],
                [
                    'id' => 'ava_price',
                    'title' => "本月平均客单价",
                    'amount' => $order_amount > 0 ? round($total_price / $order_amount, 2) : 0,
                    'icon' => "money"
                ],
                [
                    'id' => 'ava_price',
                    'title' => "本月退款金额",
                    'amount' => $total_refund_price,
                    'icon' => "money"
                ],
            ]);
        }
    }

    /**
     * 产品销售
     */
    public function getProductStat($start_date = null, $end_date = null, $filter)
    {
        if (empty($start_date) || empty($end_date))
            return null;

        $products = OrderProduct::from("order_product as op")
            ->selectRaw("FROM_UNIXTIME(`wx_o`.create_time,'%Y-%m-%d') as cdate,`wx_p`.category_id,`wx_s`.title as shop_title,`wx_stall`.title as stall_title,`wx_op`.product_title,`wx_op`.product_price,`wx_op`.product_id,`wx_op`.stall_id,`wx_op`.shop_id,`wx_op`.amount,(`wx_op`.amount*`wx_op`.product_price) as total_price")
            ->join("order as o", "o.id", "=", "op.order_id")
            ->join("stall", "stall.id", "=", "op.stall_id")
            ->join("product as p", "p.id", "=", "op.product_id")
            ->join("supplier as s", "s.id", "=", "op.shop_id")
            ->when(!empty($filter['skey']), function ($q) use ($filter) {
                $q->where("p.title", "like", "%{$filter['skey']}%");
            })
            ->when(!empty($filter['shop_id']), function ($q) use ($filter) {
                $q->where("o.shop_id", "=", intval($filter['shop_id']));
            })
            ->when(!empty($filter['stall_title']), function ($q) use ($filter) {
                $q->where("stall.title", "like", "%{$filter['stall_title']}%");
            })
            ->whereIn("o.status", [10, 20])
            ->whereBetween("o.pay_time", [strtotime($start_date), strtotime($end_date)])
            ->orderBy("cdate", "desc")
            ->orderBy("op.amount", "desc")
            ->get()
            ->toArray();

        if (count($products) == 0)
            return null;

        $categoryList = ProductCategory::query()->whereIn("id", get_column($products, "category_id"))->get(['id', 'title'])->toArray();
        $categoryList = ass_column($categoryList, "id");
        $productList = ass_column($products, "product_id", true);
        $stat = [];
        foreach ($productList as $product_id => $prodcts) {
            $timeList = ass_column($prodcts, "cdate", true);
            $category_title = $categoryList[$products[0]['category_id']]['title'];

            foreach ($timeList as $dk => $time) {
                $total_price = floatval(array_sum(get_column($time, 'total_price')));
                $total_amount = floatval(array_sum(get_column($time, 'amount')));

                $stat[] = [
                    'shop_title' => $time[0]['shop_title'],
                    'stall_title' => $time[0]['stall_title'],
                    'category_title' => $category_title,
                    'product_title' => $time[0]['product_title'],
                    'amount' => $total_amount,
                    'total_price' => $total_price, //总交易额
                    'product_price' => $time[0]['product_price'], //商品售价
                    'cdate' => $dk
                ];
            }
        }

        if (empty($stat))
            return null;
        array_multisort(array_column($stat, "cdate"), SORT_DESC, $stat);
        if ($filter['isR'] == 1)
            return $stat;

        $stat = ass_column($stat, "cdate", true);

        $arr = [];
        foreach ($stat as $k => &$v) {
            array_multisort(array_column($v, "amount"), SORT_DESC, $v);
            foreach ($v as $sk => &$sv) {
                $sv['isFirst'] = $sk == 0;
                $sv['sameIndex'] = count($v);
                $arr[] = $sv;
            }
        }

        return $arr;
    }

    /**
     * 店铺统计
     * @param $start_time
     * @param $end_time
     * @param $filter
     */
    public function statShop($start_date, $end_date, $filter)
    {
        if (empty($start_date) || empty($end_date))
            return null;

        $orderList = Order::from("order as o")
            ->selectRaw("`wx_o`.id,`wx_o`.total_price,`wx_o`.shop_id,`wx_o`.express_price,`wx_o`.bag_price,`wx_s`.title as shop_title,FROM_UNIXTIME( `wx_o`.create_time, '%Y-%m-%d' ) AS cdate")
            ->join("supplier as s", "s.id", "=", "o.shop_id")
            ->when(!empty($filter['shop_id']), function ($q) use ($filter) {
                return $q->where("o.shop_id", "=", intval($filter['shop_id']));
            })
            ->whereIn('o.status', [10, 20])
            ->whereBetween("o.pay_time", [strtotime($start_date), strtotime($end_date)])
            ->orderBy("cdate", "desc")
            ->orderBy("o.shop_id", "desc")
            ->get()
            ->toArray();
        $shopOrderList = ass_column($orderList, "shop_id", true);

        $stat = [];
        foreach ($shopOrderList as $k => $shopOrder) {
            $timeList = ass_column($shopOrder, "cdate", true);

            foreach ($timeList as $dk => $time) {
                $total_price = formatNum(array_sum(get_column($time, 'total_price')));
                $total_express_price = formatNum(array_sum(get_column($time, 'express_price')));
                $total_bag_price = formatNum(array_sum(get_column($time, 'bag_price')));
                $product_price = formatNum($total_price - $total_bag_price - $total_express_price);
                $stat[] = [
                    'shop_title' => $time[0]['shop_title'],
                    'amount' => count($time),
                    'total_price' => $total_price,
                    'express_price' => $total_express_price,
                    'bag_price' => $total_bag_price,
                    'product_price' => $product_price,
                    'cdate' => $dk
                ];
            }
        }

        if (empty($stat))
            return null;
        array_multisort(array_column($stat, "cdate"), SORT_DESC, $stat);

        if ($filter['isR'] == 1)
            return $stat;

        $data = ass_column($stat, "cdate", true);

        $arr = [];
        foreach ($data as $k => &$v) {
            foreach ($v as $sk => &$sv) {
                $sv['isFirst'] = $sk == 0;
                $sv['sameIndex'] = count($v);
                $arr[] = $sv;
            }
        }

        return $arr;
    }

    /**
     * 档口统计
     * @param $start_time
     * @param $end_time
     * @param $filter
     */
    public function statStall($start_date, $end_date, $filter)
    {
        if (empty($start_date) || empty($end_date))
            return null;

        $products = OrderProduct::from("order_product as op")
            ->selectRaw("`wx_op`.order_id,FROM_UNIXTIME(`wx_o`.create_time,'%Y-%m-%d') as cdate,`wx_op`.type,`wx_op`.bag_price,`wx_op`.type,`wx_op`.product_price,`wx_op`.stall_id,`wx_op`.shop_id,`wx_op`.amount,(`wx_op`.amount*`wx_op`.product_price) as total_price,(`wx_op`.amount*`wx_op`.bag_price) as total_bag_price")
            ->join("order as o", "o.id", "=", "op.order_id")
            ->join("stall", "stall.id", "=", "op.stall_id")
            ->when(!empty($filter['shop_id']), function ($q) use ($filter) {
                return $q->where("o.shop_id", "=", intval($filter['shop_id']));
            })
            ->when(!empty($filter['stall_title']), function ($q) use ($filter) {
                $q->where("stall.title", "like", "%{$filter['stall_title']}%");
            })
            ->whereIn("o.status", [10, 20])
            ->whereBetween("o.pay_time", [strtotime($start_date), strtotime($end_date)])
            ->get()
            ->toArray();

        $shopProductList = ass_column($products, "shop_id", true);

        $stat = [];
        foreach ($shopProductList as $k => $shopProduct) {//店铺
            $shop_title = Supplier::query()->where('id', $k)->value("title");
            $stallProductList = ass_column($shopProduct, "stall_id", true);

            //档口
            foreach ($stallProductList as $sk => $stallProduct) {
                $stall_title = Stall::query()->where("id", $sk)->value("title");
                $timeList = ass_column($stallProduct, "cdate", true);

                foreach ($timeList as $dk => $time) {
                    $stat[] = [
                        'shop_title' => $shop_title,
                        'stall_title' => $stall_title,
                        'amount' => count($time),
                        'total_price' => formatNum(array_sum(get_column($time, 'total_price'))),
                        'total_bag_price' => formatNum(array_sum(get_column($time, 'total_bag_price'))),
                        'cdate' => $dk,
                    ];
                }
            }
        }
        if (empty($stat))
            return null;
        array_multisort(array_column($stat, "cdate"), SORT_DESC, $stat);

        if ($filter['isR'] == 1)
            return $stat;

        $stat = ass_column($stat, "cdate", true);

        $arr = [];
        foreach ($stat as $k => &$v) {
            foreach ($v as $sk => &$sv) {
                $sv['isFirst'] = $sk == 0;
                $sv['sameIndex'] = count($v);
                $arr[] = $sv;
            }
        }
        return $arr;
    }

    /**
     * 档口明细
     * @param $stall_id
     * @param $start_time
     * @param $end_time
     * @return null
     */
    public function statStallDetail($stall_id, $start_time, $end_time)
    {
        if (empty($start_date) || empty($end_date))
            return null;

        $products = OrderProduct::from("order_product as op")
            ->selectRaw("`wx_op`.order_id,FROM_UNIXTIME(`wx_o`.create_time,'%Y-%m-%d') as cdate,`wx_op`.type,`wx_op`.bag_price,`wx_op`.type,`wx_op`.product_price,`wx_op`.stall_id,`wx_op`.shop_id,`wx_op`.amount,(`wx_op`.amount*`wx_op`.product_price) as total_price,(`wx_op`.amount*`wx_op`.bag_price) as total_bag_price")
            ->join("order as o", "o.id", "=", "op.order_id")
            ->whereIn("o.status", [10, 20])
            ->where("op.stall_id", $stall_id)
            ->whereBetween("o.pay_time", [strtotime($start_date), strtotime($end_date . " 23:59:59")])
            ->orderBy("o.create_time", "asc")
            ->get()
            ->toArray();

        return $products;
    }


}
